#include "event.h"
Event::Event() : draw_(-10, 10, -10, 10) {
    initlrExprs();
    lformula_.initNUm(lexpres_);
    rformula_.initNUm(rexpres_);

    draw_.Setflrfo(lformula_, rformula_);

    event_ = new SDL_Event;
    font_ = new Font("./default.ttf", 30);
}

Event::~Event() {
    delete event_;
    delete font_;
    event_ = nullptr;
}

void Event::EventLoop() {
    while (!isquit_) {
        fps_time_ = SDL_GetTicks();

        EventHandle();

        if (!isrender_) {  // 不按键就停在这前面
            if (SDL_GetTicks() - fps_time_ < MIN_FPS_TIME) {
                SDL_Delay(SDL_GetTicks() - fps_time_);
            }
            continue;
        }

        // 一步一步画
        // 用totalStep_控制画网格还是函数图像
        // 走一步画一下网格，再走一步画图，然后重置
        if (nextStep_) {
            if (totalStep_ == 1) {
                SDL_SetRenderTarget(draw_.GetRenderer(), draw_.GetGrid());
                draw_.drawCurGrid();
                draw_.drawCardinate();
                draw_.SetPenColor4Sloutions();
                SDL_SetRenderTarget(draw_.GetRenderer(),nullptr);
            }
            else if (totalStep_ == 2) {
                SDL_SetRenderTarget(draw_.GetRenderer(), draw_.GetGraph());
                draw_.step();
                draw_.drawCardinate();
                totalStep_ = 0;
                draw_.SetPenColor4Sloutions();
                SDL_SetRenderTarget(draw_.GetRenderer(),nullptr);
            }
            nextStep_ = false;
        }

        draw_.SetPenColor4Undefined();
        SDL_RenderClear(draw_.GetRenderer());  // 启动时画面会设置为未确定区域颜色

        if (renderGraph_)
            SDL_RenderCopy(draw_.GetRenderer(), draw_.GetGraph(), nullptr, nullptr);
        if (renderGrid_)
            SDL_RenderCopy(draw_.GetRenderer(), draw_.GetGrid(), nullptr, nullptr);
        if (renderFont_) {
            I_type x = draw_.pixelToRealH(intervalFromReals<I_type>(dragStart_.x, dragEnd_.x));
            I_type y = draw_.pixelToRealV(intervalFromReals<I_type>(draw_.Window::GetHeight()-dragStart_.y, draw_.Window::GetHeight()-dragEnd_.y));
            I_type fx = draw_.gfx(x);
            BoolInterval fy(false, false);
            if (draw_.compare_ == 0) {
                fy = draw_.gfyg(lformula_, rformula_, fx, y);
            }
            else {
                fy = draw_.gfyl(lformula_, rformula_, fx, y);
            }

            char buf[1024] = {0};
            snprintf(buf, sizeof(buf)-1, "x = (%.3f, %.3f) \ny = (%.3f, %.3f)\n def = (%d, %d) \n",
                        x.unsafeA(), x.unsafeB(),
                        y.unsafeA(), y.unsafeB(),
                        fy.a(), fy.b());
            std::string str(buf);
            SDL_SetRenderTarget(draw_.GetRenderer(), draw_.GetFontgraph());
            font_->Draw(draw_.GetRenderer(), str, fontxy_.x, fontxy_.y, 400, 20);
            SDL_SetRenderTarget(draw_.GetRenderer(), nullptr);
            SDL_RenderCopy(draw_.GetRenderer(), draw_.GetFontgraph(), nullptr, nullptr);
        }

        if (dragging_) {
            SDL_SetRenderDrawColor(draw_.GetRenderer(), 144, 185, 235, 120);
            int rx = std::min(dragStart_.x, dragEnd_.x);
            int ry = std::min(dragStart_.y, dragEnd_.y);
            SDL_Rect rect = {rx, ry, abs(dragEnd_.x-dragStart_.x), abs(dragEnd_.y-dragStart_.y)};
            SDL_RenderFillRect(draw_.GetRenderer(), &rect);
            draw_.SetPenColor4Undefined();
        }

        //SDL_RenderCopy(isrender_, texture_, NULL, NULL);
        SDL_RenderPresent(draw_.GetRenderer());

        isrender_ = false;
    }
    std::cout << "GoodBye!" << std::endl;
}

void Event::EventHandle() {
    while (SDL_PollEvent(event_)) {
        if (event_->type == SDL_QUIT) {
            isquit_ = true;
        }
        else if (event_->type == SDL_KEYUP) {
            if (event_->key.keysym.sym == SDLK_q) {
                isquit_ = true;
            }
            else if (event_->key.keysym.sym == SDLK_SPACE) {
                isrender_ = true;
                nextStep_ = true;
                ++totalStep_;
            }
            else if (event_->key.keysym.sym == SDLK_o) {
                draw_.SetStartStatus();
                renderGrid_ = true;
                renderGraph_ = false;
                SDL_SetRenderTarget(draw_.GetRenderer(), draw_.GetGraph());
                draw_.finish();

                draw_.SetPenColor4Sloutions();
                SDL_SetRenderTarget(draw_.GetRenderer(), nullptr);

                SDL_SetRenderTarget(draw_.GetRenderer(), draw_.GetGrid());
                draw_.drawCurGrid();

                draw_.SetPenColor4Sloutions();
                SDL_SetRenderTarget(draw_.GetRenderer(), nullptr);

                isrender_ = true;
            }
            else if (event_->key.keysym.sym == SDLK_g) {
                renderGrid_ = !renderGrid_;
                isrender_ = true;
            }
            else if (event_->key.keysym.sym == SDLK_f) {
                renderGraph_ = !renderGraph_;
                isrender_ = true;
            }
            else if (event_->key.keysym.sym == SDLK_i) {
                renderFont_ = !renderFont_;
                isrender_ = true;
            }
        }
        else if (event_->type == SDL_MOUSEBUTTONUP) {
            if (event_->button.button == SDL_BUTTON_LEFT) {
                dragging_ = false;
                dragEnd_.x = event_->button.x;
                dragEnd_.y = event_->button.y;
                FlashFont();
            }
            else if (event_->button.button == SDL_BUTTON_RIGHT) {
                fontxy_.x = event_->motion.x-200;
                fontxy_.y = event_->motion.y+10;
                FlashFont();
            }
        }
        else if (event_->type == SDL_MOUSEBUTTONDOWN) {
                if (event_->button.button == SDL_BUTTON_LEFT) {
                    isrender_ = true;
                    dragging_ = true;
                    dragStart_.x = dragEnd_.x = event_->motion.x;
                    dragStart_.y = dragEnd_.y = event_->motion.y;
                }
        }
        else if (event_->type == SDL_MOUSEMOTION) {
            if (dragging_) {
                isrender_ = true;
                dragEnd_.x = event_->motion.x;
                dragEnd_.y = event_->motion.y;
            }
        }
    }
}

void Event::FlashFont() {
    isrender_ = true;
    SDL_SetRenderDrawColor(draw_.GetRenderer(), 0,0,0,0);
    SDL_SetRenderTarget(draw_.GetRenderer(), draw_.GetFontgraph());
    SDL_RenderClear(draw_.GetRenderer());
    font_->Clear(draw_.GetRenderer());
    SDL_SetRenderTarget(draw_.GetRenderer(), nullptr);
    draw_.SetPenColor4Sloutions();
}

void Event::initlrExprs() {
    int lock = 0;
    string allexpres = "";
    cin >> allexpres;
    for (uint32_t i = 0; i < allexpres.length(); ++i) {
        if (allexpres[i] == '<' || allexpres[i] == '>') {

            if (allexpres[i] == '<') {
                draw_.compare_ += 1;
            }
            lock += 1;
            continue;
        }
        if (lock == 0) {
            lexpres_ += allexpres[i];
        }
        else {
            rexpres_ += allexpres[i];
        }
    }
}
